package com.gan.simple_init.util;

import com.gan.simple_init.common.constant.RedisConstant;
import com.gan.simple_init.common.constant.UserConstant;
import com.gan.simple_init.common.exception.BusinessException;
import com.gan.simple_init.mapper.SysUserMapper;
import com.gan.simple_init.model.user.entity.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;

/**
 * @author gbw
 * @date 2023/8/9
 * 用户缓存工具类
 */
@Component
public class UserCacheUtil {
    /**
     * 装载token工具类
     */
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    /**
     * redis工具类
     */
    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private static SysUserMapper sysUserMapper;

    /**
     * 过期时间
     */
    @Value("${jwt.refreshExpiration}")
    private Long refreshExpiration;

    /**
     * 生成 token 并将其放入到 redis 中
     *
     * @param httpServletRequest
     * @param loginUser
     * @return
     */
    public String genTokenToCache(HttpServletRequest httpServletRequest, LoginUser loginUser) {
        String token = jwtTokenUtil.generateToken(loginUser, loginUser.getId());
        // 将 token 放到 redis
        redisUtil.set(RedisConstant.USER_LOGIN_KEY + token, "token", refreshExpiration);
        // 将用户信息放到 redis
        redisUtil.set(RedisConstant.USER_LOGIN_KEY + loginUser.getUsername(), loginUser);
        // 如果请求头中包含 token 则移除 redis 中对应的 token
        jwtTokenUtil.removeRedisToken(httpServletRequest);
        return token;
    }

    /**
     * 从 authentication 中获取用户对象
     *
     * @return SysUser 用户对象
     */
    public static LoginUser getUserCache() {
        LoginUser sysAccount = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof UsernamePasswordAuthenticationToken) {
            UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
            sysAccount = (LoginUser) authenticationToken.getPrincipal();
        }
        if (sysAccount == null) {
            throw new BusinessException("用户信息不存在!");
        }
        return sysAccount;
    }

    /**
     * 检查用户是否为管理员
     *
     */
    public static Boolean isAdmin() {
        LoginUser loginUser = getUserCache();
        Collection<? extends GrantedAuthority> authorities = loginUser.getAuthorities();
        for (Object o : authorities) {
            if (UserConstant.ROLE_NAME_ADMIN.equals(o.toString())){
                return true;
            }
        }

        return false;
    }

    /**
     * 获得用户 id
     *
     */
    public static Long getUserId() {
        LoginUser loginUser = getUserCache();
        return loginUser.getId();
    }

    /**
     * 获得用户角色
     *
     */
    public static String getUserRole() {
        LoginUser loginUser = getUserCache();
        List<String> roles = sysUserMapper.selectRolesById(loginUser.getId());
        return StringUtils.join(roles,",");
    }


    /**
     * 确认用户是否拥有某个权限
     *
     */
    public static boolean checkUserRole(String roleName) {
        return getUserRole().contains(roleName);
    }
}
